import { Injectable, Inject } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { zip, of } from 'rxjs'
import { catchError } from 'rxjs/operators'
import { NzIconService } from 'ng-zorro-antd'
import { MenuService, SettingsService, TitleService, ALAIN_I18N_TOKEN } from '@delon/theme'
import { ACLService, ACLType } from '@delon/acl'
import { TranslateService } from '@ngx-translate/core'

import { I18NService } from '../i18n/i18n.service'
import { TreeService } from '@shared/services/tree.service'
import { ICONS_AUTO } from '../../../style-icons-auto'
import { ICONS } from '../../../style-icons'
import { User } from '@shared/interfaces/user'
import { COMB_URL } from 'app/utils/contraints'
import { DA_SERVICE_TOKEN, ITokenService, JWTTokenModel } from '@delon/auth'
import { Validators } from '@angular/forms'
import { utilsValidatorsRequired } from 'app/utils/validator'
Validators.required = utilsValidatorsRequired
/**
 * 用于应用启动时
 * 一般用来获取应用所需要的基础数据等
 */
@Injectable()
export class StartupService {
  constructor(
    iconSrv: NzIconService,
    private menuService: MenuService,
    private translate: TranslateService,
    @Inject(ALAIN_I18N_TOKEN) private i18n: I18NService,
    @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
    private settingService: SettingsService,
    private aclService: ACLService,
    private titleService: TitleService,
    private httpClient: HttpClient,
    private treeService: TreeService,
  ) {
    iconSrv.addIcon(...ICONS_AUTO, ...ICONS)
  }

  private viaHttp(resolve: any, reject: any) {
    const jwtModel = this.tokenService.get<JWTTokenModel>(JWTTokenModel)
    const zip$ = zip(
      this.httpClient.get(`assets/i18n/${this.i18n.defaultLang}.json?nocache=${new Date().getTime()}`),
      this.httpClient
        .get(`${COMB_URL}/auth/session`, {
          headers: {
            Authorization: `Bearer ${jwtModel.token}`,
          },
        })
        .pipe(
          catchError(() => {
            return of({
              data: [],
              roles: [],
            })
          }),
        ),
    )

    zip$
      .pipe(
        // 接收其他拦截器后产生的异常消息
        catchError(err => {
          const [langData, appData] = err
          resolve(null)
          return [langData, appData]
        }),
      )
      .subscribe(
        response => {
          if (!response) {
            return
          }
          const [langData, appData] = response
          // setting language data
          this.translate.setTranslation(this.i18n.defaultLang, langData)
          this.translate.setDefaultLang(this.i18n.defaultLang)

          if (!appData) {
            return
          }

          // application data
          const res: User = appData
          // 应用信息：包括站点名、描述、年份
          // this.settingService.setApp(res.app)
          // 用户信息：包括姓名、头像、邮箱地址, 登录后会保存用户的设置信息
          this.settingService.setUser(res)

          if (!res.roles) {
            res.roles = []
          }
          if (!res.data) {
            res.data = []
          }
          // ACL：设置权限
          const aclValue: ACLType = {
            role: res.roles.map(r => `${r.roleId}`),
            ability: res.data.map(p => p.menuState),
          }
          this.aclService.set(aclValue)

          // 初始化菜单
          const menu = this.treeService.computeMenuTree(res.data)
          this.menuService.add(menu)
          // 设置页面标题的后缀
          // this.titleService.suffix = res.app.name
        },
        () => {},
        () => {
          resolve(null)
        },
      )
  }

  private viaMockI18n(resolve: any, reject: any) {
    this.httpClient.get(`assets/i18n/${this.i18n.defaultLang}.json`).subscribe(langData => {
      this.translate.setTranslation(this.i18n.defaultLang, langData)
      this.translate.setDefaultLang(this.i18n.defaultLang)

      this.viaMock(resolve, reject)
    })
  }

  private viaMock(resolve: any, reject: any) {
    // const tokenData = this.tokenService.get();
    // if (!tokenData.token) {
    //   this.injector.get(Router).navigateByUrl('/passport/login');
    //   resolve({});
    //   return;
    // }
    // mock
    const app: any = {
      name: `ng-alain`,
      description: `Ng-zorro admin panel front-end framework`,
    }
    const user: any = {
      name: 'Admin',
      avatar: './assets/tmp/img/avatar.jpg',
      email: 'cipchk@qq.com',
      token: '123456789',
    }
    // 应用信息：包括站点名、描述、年份
    this.settingService.setApp(app)
    // 用户信息：包括姓名、头像、邮箱地址
    this.settingService.setUser(user)
    // ACL：设置权限为全量
    this.aclService.setFull(true)
    // 初始化菜单
    this.menuService.add([
      {
        text: '主导航',
        group: true,
        children: [
          {
            text: '仪表盘',
            link: '/dashboard',
            icon: { type: 'icon', value: 'appstore' },
          },
          {
            text: '快捷菜单',
            icon: { type: 'icon', value: 'rocket' },
            shortcutRoot: true,
          },
        ],
      },
    ])
    // 设置页面标题的后缀
    this.titleService.suffix = app.name

    resolve({})
  }

  load(): Promise<any> {
    // only works with promises
    // https://github.com/angular/angular/issues/15088
    return new Promise((resolve, reject) => {
      // http
      this.viaHttp(resolve, reject)
      // mock：请勿在生产环境中这么使用，viaMock 单纯只是为了模拟一些数据使脚手架一开始能正常运行
      // this.viaMockI18n(resolve, reject);
    })
  }
}
